package cn.bitkit.component.sensitive;

import cn.bitkit.base.annotation.Sensitive;
import cn.bitkit.base.exception.BusinessAssert;
import cn.bitkit.component.context.SpringContext;
import cn.bitkit.base.util.ReflectUtil;
import cn.bitkit.base.util.StringUtil;

import java.lang.reflect.Field;
import java.util.List;

/**
 * @author changbo
 */
public class SensitiveHandler {

    /**
     * 脱敏处理
     */
    public static <T> void encode(T source){
        BaseSensitiveService baseSensitiveService = SpringContext.getAssertedBean(BaseSensitiveService.class);
        List<Field> list = ReflectUtil.getFields(source.getClass());
        list.forEach( field -> {
            Sensitive sensitive = field.getAnnotation(Sensitive.class);
            if(sensitive == null){
                return;
            }
            Object value = ReflectUtil.getValue(source, field);
            if(value instanceof String val){
                if(StringUtil.hasValue(sensitive.encryptField())){
                    String encValue = baseSensitiveService.encrypt(val, sensitive);
                    String fieldName = StringUtil.decideValue(sensitive.encryptField(), field.getName()+ sensitive.encryptFieldAuto());
                    ReflectUtil.setValue(source, fieldName, encValue);
                }
                if(StringUtil.hasValue(sensitive.hashField())){
                    String hashValue = baseSensitiveService.hash(val, sensitive);
                    String fieldName = StringUtil.decideValue(sensitive.hashField(), field.getName()+ sensitive.hashFieldAuto());
                    ReflectUtil.setValue(source, fieldName, hashValue);
                }
                if(StringUtil.hasValue(sensitive.maskField())){
                    String maskValue = baseSensitiveService.mask(val, sensitive);
                    String fieldName = StringUtil.decideValue(sensitive.maskField(), field.getName()+ sensitive.maskFieldAuto());
                    ReflectUtil.setValue(source, fieldName, maskValue);
                }
            }
        });

    }

    /**
     * 解密处理
     */
    public static void decode(Object source){
        BaseSensitiveService baseSensitiveService = SpringContext.getAssertedBean(BaseSensitiveService.class);
        List<Field> list = ReflectUtil.getFields(source.getClass());
        list.forEach( field -> {
            Sensitive sensitive = field.getAnnotation(Sensitive.class);
            if(sensitive == null){
                return;
            }
            if(StringUtil.hasValue(sensitive.encryptField())){
                Object encValue = ReflectUtil.getValue(source, sensitive.encryptField());
                if(encValue instanceof String encVal){
                    String decValue = baseSensitiveService.decrypt(encVal, sensitive);
                    ReflectUtil.setValue(source, field, decValue);
                }
            }
        });
    }

}
